import os
import socket
import json
from datetime import datetime
from time import sleep

def get_structure(directory):
    structure = {'dirs': [], 'files': {}}
    for root, dirs, files in os.walk(directory):
        for dir in dirs:
            full_path = os.path.join(root, dir)
            rel_path = os.path.relpath(full_path, directory)
            structure['dirs'].append(rel_path)
        
        for file in files:
            full_path = os.path.join(root, file)
            rel_path = os.path.relpath(full_path, directory)
            mtime = os.path.getmtime(full_path)
            size = os.path.getsize(full_path)
            structure['files'][rel_path] = {'mtime': mtime, 'size': size}
    return structure

def send_file(sock, file_path, rel_path):
    file_size = os.path.getsize(file_path)
    metadata = json.dumps({'path': rel_path, 'size': file_size})
    sock.send(f"{metadata}\n".encode())
    
    with open(file_path, 'rb') as f:
        while True:
            chunk = f.read(8192000)
            if not chunk:
                break
            sock.send(chunk)

def start_server(directory, host, port):
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind((host, port))
        s.listen(1)
        print(f"Server listening on {host}:{port}")
        
        while True:
            conn, addr = s.accept()
            print(f"Connected by {addr}")
            
            try:
                # Send directory structure
                structure = get_structure(directory)
                conn.send(json.dumps(structure).encode() + b'\n')
                
                # Receive list of needed files
                needed_files = json.loads(conn.recv(4096000).decode())
                print(needed_files)
                # Send needed files
                for rel_path in needed_files:
                    full_path = os.path.join(directory, rel_path)
                    send_file(conn, full_path, rel_path)
                    sleep(1)
                
                conn.send(b"DONE\n")
                print("Sync completed")
                
            except Exception as e:
                print(f"Error: {e}")
            finally:
                conn.close()

if __name__ == "__main__":
    directory = r"c:\sscms-7.3.0-win-x64"
    start_server(directory, "0.0.0.0", 212)